import { Camera, RenderTexture, SpriteFrame, Texture2D, UITransform, Vec2, Vec3, gfx, postProcess, renderer, rendering } from "cc";
import { GaussianBlur } from "./GaussianBlur";

export class GaussianBlurPass extends postProcess.SettingPass {

    // private framePool: ObjectPool<SpriteFrame> = null;
    // private renderTexturePool: ObjectPool<RenderTexture> = null;

    constructor() {
        super();
        // this.framePool = new ObjectPool<SpriteFrame>();
        // this.renderTexturePool = new ObjectPool<RenderTexture>();

        // for (let i = 0; i < 10; i++) {
        //     this.framePool.fill(new SpriteFrame);
        //     this.renderTexturePool.fill(new RenderTexture());
        // }
    }

    private hasBlur: boolean = false;

    get setting() {
        return this.getSetting(GaussianBlur);
    }

    checkEnable(camera: renderer.scene.Camera) {
        // 判断次后效是否开启

        let enable = super.checkEnable(camera);
        if (postProcess.disablePostProcessForDebugView()) {
            enable = false;
        }
        return enable && this.setting.material != null;
    }

    name = 'GaussianBlurPass';
    outputNames = ['GaussianBlurMap'];

    private _blurPreview(camera: renderer.scene.Camera) {
        const setting = this.setting;
        let w, h;
        [w, h] = [camera.window.width, camera.window.height];

        // let frame = this.framePool.acquire();
        // let texture = this.renderTexturePool.acquire();
        let frame = new SpriteFrame()
        let texture = new RenderTexture();

        texture.initialize({
            name: "s",
            width: w,
            height: h,
        });

        setting.preview.node.setScale(new Vec3(1, -1, 1));
        setting.mainCamera.targetTexture = texture;


        setting.scheduleOnce(() => {
            frame.texture = texture;

            setting.previewRenderTexture = texture
            setting.preview.spriteFrame = frame;
            // setting.preview.node.getComponent(UITransform).width = w;
            setting.mainCamera.targetTexture = null;

            // this.framePool.release(frame);
            // this.renderTexturePool.release(texture);
        }, 0.1);
    }

    public render(camera: renderer.scene.Camera, ppl: rendering.Pipeline): void {
        const setting = this.setting;
        const previewSprite = setting.preview;
        if (!setting.material) {
            return;
        }
        // 节点的数据
        let passContext = this.context;
        passContext.material = setting.material;

        const cameraID = this.getCameraUniqueID(camera);
        const cameraName = `Camera${cameraID}`;
        const passViewport = passContext.passViewport;
        if (setting.clearBack) {
            // 清理背景
            passContext.clearBlack();
        }

        const format = gfx.Format.RGBA8;

        // 需要使用上一个处理流程结束后的画面内容
        let input = this.lastPass!.slotName(camera, 0);
        console.log("input is ", input);
        for (let i = 0; i < setting.iterations; ++i) {
            passContext
                .updatePassViewPort() // 相对分辨率大小
                .addRenderPass(`blur-x`, `blur-x${cameraID}`) // 执行绘制流程 blur-x表示shader中的 pass名称
                .setPassInput(input, 'outputResultMap') // input: 自定义管线资源分配的资源名 shaderName: 对应shader的 uniform sampler2D
                .addRasterView('GaussianBlurMap_TMP', format) // 输出结果
                .blitScreen(0) // 执行绘制 pass0
                .version();

            passContext
                .updatePassViewPort()
                .addRenderPass(`blur-y`, `blur-y${cameraID}`)
                .setPassInput('GaussianBlurMap_TMP', 'outputResultMap')
                .addRasterView(this.slotName(camera), format) // 输出的RenderTexture名称 及 RenderTexture的格式
                .blitScreen(1) // pass1
                .version();
            input = this.slotName(camera);
        }

        this._blurPreview(camera);
        // if (!this.hasBlur) {
        //     this.hasBlur = true;
        // }
    }
}


let builder = rendering.getCustomPipeline("Custom") as postProcess.PostProcessBuilder;
if (builder) {
    // 加入到引擎pass列表中才能够执行
    builder.insertPass(new GaussianBlurPass(), postProcess.BlitScreenPass);
}